package com.defysoft.waukids;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;

public class BaseActivity_UpPhoto extends FragmentActivity implements
		PublicConstant {

	private static final String TEMP_PHOTO_FILE = "temp.jpg"; // 임시 저장파일
	String filePath;
	public Thread firstThread;
	public Thread upThread;
	public int rcode=0;
	Bitmap resultBitmap=null;
	public ArrayList<upImageData> imageList=new ArrayList<BaseActivity_UpPhoto.upImageData>();
	public String boundary = "^***defysoft***^";
	// 데이터 경계선
	public String delimiter = "\r\n--" + boundary + "\r\n";
	
	
	/** 사진올리기 되돌아오는... */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == rcode) {	//사진 새로올리기
			if (resultCode == android.app.Activity.RESULT_OK) {
/*				if (data != null) {*/
					resultBitmap = BitmapFactory.decodeFile(filePath);
					imageList.get(rcode-5000).iv.setBackgroundColor(0x00ffffff);
					imageList.get(rcode-5000).iv.setImageBitmap(null);
					imageList.get(rcode-5000).iv.setImageBitmap(resultBitmap);//사진보이게.
					imageList.get(rcode-5000).bitmap=resultBitmap;
				/*}*/
			}
		}
	}

	public void setStartData() {// 처음 레이아웃 지정 메소드
	}

	public void onNetworkCallback(int _result, String _message) { // 네트워크에서
																	// 콜백된메소드
		sendMessage(_result, _message);
	}

	public void startNetwork(int choice) { // 스레드로 네트워크 체크전 네트워크 상태확인메소드
		if (!isNetworkStat(this)) {
			showErrPopup();
		} else {
			if (firstThread != null) {
				firstThread.interrupt();
			}
			startThread(choice);

		}
	}
	
	public void startupNetwork(int choice) { // 스레드로 네트워크 체크전 네트워크 상태확인메소드
		if (!isNetworkStat(this)) {
			showErrPopup();
		} else {
			if (firstThread != null) {
				firstThread.interrupt();
			}
			upImageThread(choice);
		}
	}
	
	public void startThread(int choice) { // thread 시작을 위한 메소드
	}
	
	public void upImageThread(int choice){
	}

	public String publicHttpCallback(String uri, String param) { // 기본 http통신 흐름
		String msg = "";
		try {
			URL url = new URL(uri);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(30 * 1000); // 30 secs
			conn.setReadTimeout(30 * 1000); // 30 secs
			conn.setRequestMethod("POST");
			conn.setUseCaches(false);
			conn.setRequestProperty("Accept-Charset", "UTF-8");
			conn.setRequestProperty("Accept_Language",
					"ko-kr,ko;q=0;en-us;q=0,en;q=0.3");

			OutputStream outStream = conn.getOutputStream();
			outStream.write(param.getBytes());
			outStream.flush();
			outStream.close();
			int nResCode = conn.getResponseCode();
			if (nResCode != HttpURLConnection.HTTP_OK) {
				String strResMsg = conn.getResponseMessage();
				Exception e = new Exception(strResMsg);
				throw e;
			}
			BufferedReader br = new BufferedReader(new InputStreamReader(
					conn.getInputStream()));
			String checkmsg;
			msg = br.readLine();
			while ((checkmsg = br.readLine()) != null) {
				msg += ("\n" + checkmsg);
			}
		} catch (Exception e) {
			onNetworkCallback(CATCH_EXCEPTION,
					"publicHttpCallback" + e.toString());// 실패에 대한 네트워크 콜백을
															// 지정한다.

		}
		return msg.trim();
	}

	public void sendMessage(int nMessage) { // 핸들링하기위한 메세지 전송
		Message msg = this.m_Handler.obtainMessage(nMessage);
		this.m_Handler.sendMessage(msg);
	}

	public void sendMessage(int nMessage, String message) { // 핸들링하기위한 메세지 전송
		Message msg = this.m_Handler.obtainMessage(nMessage);
		msg.obj = message;
		this.m_Handler.sendMessage(msg);
	}

	protected final Handler m_Handler = new Handler() {// 센드된 메세지를 핸들링메소드로 넘기는
														// 메소드

		@Override
		public void handleMessage(Message message) {
			handlingMessage(message);
		}
	};

	protected void handlingMessage(Message _message) {// send된 메세지를 처리하는부분 재지정해서
														// 사용

	}

	public void showPopup(String _title, String _message, final int _returnID) {// 안내창을띄우기위한메소드
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle(_title);
		alert.setMessage(_message);
		alert.setNegativeButton("OK", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				if (_returnID != 0) {
					sendMessage(_returnID);
				}
			}
		});
		alert.setCancelable(true);
		alert.show();
	}

	public void showErrPopup() {// 네트워크 상테 애러메세지
		endDIal();
		showPopup("네트워크 오류", "네트워크 상태를 확인하세요", 0);
	}

	public boolean isNetworkStat(Context context) { // 네트워크 상태 체크 메소드
		ConnectivityManager manager = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo mobile = manager
				.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
		NetworkInfo wifi = manager
				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		NetworkInfo lte_4g = manager
				.getNetworkInfo(ConnectivityManager.TYPE_WIMAX);
		boolean blte_4g = false;
		if (lte_4g != null)
			blte_4g = lte_4g.isConnected();
		if (mobile != null) {
			if (mobile.isConnected() || wifi.isConnected() || blte_4g)
				return true;
		} else {
			if (wifi.isConnected() || blte_4g)
				return true;
		}
		return false;
	}

	public void startDIal() {
		startActivityForResult(new Intent(this, Prodialog.class),
				PublicConstant.PRODIALOG_RESULTCODE);
	}

	public void startDIal(int setcode) {
		Intent dialintent = new Intent(this, Prodialog.class);
		dialintent.putExtra(PublicConstant.PRODIALOG_SETCODE, setcode);
		startActivityForResult(dialintent, PublicConstant.PRODIALOG_RESULTCODE);
	}

	public void endDIal() {
		finishActivity(PublicConstant.PRODIALOG_RESULTCODE);
	}

	/** image upload 세팅 */
	public void addPhotoListener(int rcode) { // 사진공간 눌리면.
		rcode+=5000;
		this.rcode=rcode;
		if (isSDCARDMOUNTED()) {
			Intent i = new Intent(
					Intent.ACTION_PICK,
					android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
			i.setType("image/*");
			i.putExtra("crop", "true");// 사진잘라서 가져오기.
			i.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri()); // 임시파일 생성.
			i.putExtra("outputFormat", // 포맷방식
					Bitmap.CompressFormat.JPEG.toString()); // jpeg는 손실형 압축,
															// png는 비손실 압축.
			
			this.startActivityForResult(i, rcode); // 사진담아서 다시 스레드 돌림(DB저장,
													// 파일업로드)
		} else {
			Toast.makeText(this, "SD카드가 발견되지 않습니다.\nSD카드가 없으면 사진을 찾을 수 없습니다.",
					Toast.LENGTH_SHORT).show();
		}
	}
	public void addPhotoListener(int rcode,int x,int y,int outx, int outy) { // 사진공간 눌리면.
		if (isSDCARDMOUNTED()) {
			rcode+=5000;
			this.rcode=rcode;
			Intent i = new Intent(
					Intent.ACTION_PICK,
					android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
			i.setType("image/*");
			i.putExtra("crop", "true");// 사진잘라서 가져오기.
			i.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri()); // 임시파일 생성.
			i.putExtra("outputFormat", // 포맷방식
					Bitmap.CompressFormat.JPEG.toString()); // jpeg는 손실형 압축,
															// png는 비손실 압축.
			
			i.putExtra("aspectX", x); // crop의 비율 
			i.putExtra("aspectY", y);
			i.putExtra("outputX", outx); //crop의 최대해상도
			i.putExtra("outputY", outy); //crop의 최대해상도
			 
			this.startActivityForResult(i, rcode); // 사진담아서 다시 스레드 돌림(DB저장,
													// 파일업로드)
		} else {
			Toast.makeText(this, "SD카드가 발견되지 않습니다.\nSD카드가 없으면 사진을 찾을 수 없습니다.",
					Toast.LENGTH_SHORT).show();
		}
	}

	/** SD카드가 마운트 되어 있는지 확인 */
	public boolean isSDCARDMOUNTED() {
		String status = Environment.getExternalStorageState();
		if (status.equals(Environment.MEDIA_MOUNTED))
			return true;
		return false;
	}

	// ///////////////////////////////////////////////////사진관련 처리
	/** 임시 저장 파일의 경로를 반환 */
	private Uri getTempUri() {
		return Uri.fromFile(getTempFile());
	}

	/** 외장메모리에 임시 이미지 파일을 생성하여 그 파일의 경로를 반환 */
	public File getTempFile() {
		if (isSDCARDMOUNTED()) {
			File f = new File(Environment.getExternalStorageDirectory(), // 외장메모리
					TEMP_PHOTO_FILE); // 임시 파일명
			filePath = f.getPath(); // 경로.
			try {
				f.delete();
				f.createNewFile(); // 외장메모리에 temp.jpg 파일 생성
			} catch (IOException e) {
			}

			return f;
		} else {

			// 내장메모리 접근하려했으나 저장까지는 되는데 불러오질못함(bitmapfactory 쪽인 안되는듯함) ㅎㅎㅎ
			return null;
		}
	}
	
	// 비트맵 사이즈 줄여서 바이트 배열로 받기
		public byte[] getbitmap(Bitmap bitmap,int detail) {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			try {

			/*	int height = bitmap.getHeight();
				int width = bitmap.getWidth();
				
				int bw = 620;
				if (bitmap.getWidth() < bw) {
					bw = bitmap.getWidth() - 10;
				}
				// 160 부분을 자신이 원하는 크기로 변경할 수 있습니다.
				bitmap = Bitmap.createScaledBitmap(bitmap, bw, height
						/ (width / bw), true);
	*/
				bitmap.compress(CompressFormat.JPEG, detail, baos);
			} catch (Exception e) {
				
			}

			return baos.toByteArray();
		}
		
		/**
		 * Map 형식으로 Key와 Value를 셋팅한다.
		 * 
		 * @param key
		 *            : 서버에서 사용할 변수명
		 * @param value
		 *            : 변수명에 해당하는 실제 값
		 * @return
		 */
		public static String setValue(String key, String value) {
			return "Content-Disposition: form-data; name=\"" + key + "\r\n\r\n"
					+ value;
		}

		/**
		 * 업로드할 파일에 대한 메타 데이터를 설정한다.
		 * 
		 * @param key
		 *            : 서버에서 사용할 파일 변수명
		 * @param fileName
		 *            : 서버에서 저장될 파일명
		 * @return
		 */
		public static String setFile(String key, String fileName) {
			return "Content-Disposition: form-data; name=\"" + key
					+ "\";filename=\"" + fileName + "\"\r\n";
		}

	
	public void addImageData(ImageView iv){
		imageList.add(new upImageData(iv));
	}
	
	
	public class upImageData{
		public ImageView iv;
		public Bitmap bitmap=null;
		public upImageData(ImageView iv){
			this.iv=iv;
		}
	}
	
	/**
	 * EXIF정보를 회전각도로 변환하는 메서드
	 * 
	 * @param exifOrientation EXIF 회전각
	 * @return 실제 각도
	 */
	public int exifOrientationToDegrees(int exifOrientation)
	{
	  if(exifOrientation == ExifInterface.ORIENTATION_ROTATE_90)
	  {
	    return 90;
	  }
	  else if(exifOrientation == ExifInterface.ORIENTATION_ROTATE_180)
	  {
	    return 180;
	  }
	  else if(exifOrientation == ExifInterface.ORIENTATION_ROTATE_270)
	  {
	    return 270;
	  }
	  return 0;
	}

	/**
	 * 이미지를 회전시킵니다.
	 * 
	 * @param bitmap 비트맵 이미지
	 * @param degrees 회전 각도
	 * @return 회전된 이미지
	 */
	public Bitmap rotate(Bitmap bitmap, int degrees)
	{
	  if(degrees != 0 && bitmap != null)
	  {
	    Matrix m = new Matrix();
	    m.setRotate(degrees, (float) bitmap.getWidth() / 2, 
	    (float) bitmap.getHeight() / 2);
	    
	    try
	    {
	      Bitmap converted = Bitmap.createBitmap(bitmap, 0, 0,
	      bitmap.getWidth(), bitmap.getHeight(), m, true);
	      if(bitmap != converted)
	      {
	        bitmap.recycle();
	        bitmap = converted;
	      }
	    }
	    catch(OutOfMemoryError ex)
	    {
	      // 메모리가 부족하여 회전을 시키지 못할 경우 그냥 원본을 반환합니다.
	    }
	  }
	  return bitmap;
	}
	
	/**
	 * 지정한 패스의 파일을 읽어서 Bitmap을 리턴(화면 사이즈에 최대한 맞춰서 리스케일 한다.)
	 * @param context
	 * 			application context
	 * @param imgFilePath
	 * 				itmap file path
	 * @return Bitmap
	 * @throws IOExeption
	 */
	
	public byte [] resizeBitmap(Context context, String imgFilePath) throws Exception{
		int quality = 100;
		// 이미지를 상황에 맞게 회전시킨다
	    ExifInterface exif = new ExifInterface(imgFilePath);
	    int exifOrientation = exif.getAttributeInt(
	    ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
	    int exifDegree = exifOrientationToDegrees(exifOrientation);
	    
		Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
		
		int displayWidth = display.getWidth();
		int displayHeight = display.getHeight();
		
		BitmapFactory.Options options_bitmap = new Options();
		options_bitmap.inPreferredConfig = Config.RGB_565;
		options_bitmap.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(imgFilePath,options_bitmap);
		
		//화면 사이즈에 가장 근접하는 이미지의 리스케일 사이즈를 구한다.
		//리스케일의 사이즈는 짝수로 지정한다. (이미지 손실을 최소화하기 위함)
		float widthScale = options_bitmap.outWidth/ displayWidth;
		Log.i("사이즈4",widthScale +"///");
		float heightScale =options_bitmap.outHeight/ displayHeight;
		Log.i("사이즈5",heightScale +"///");

		float scale = widthScale > heightScale ? widthScale : heightScale;
		
		
		BitmapFactory.Options options_bitmap_new = new Options();
		options_bitmap_new.inPreferredConfig = Config.RGB_565;
		
		
		
		
		if(scale >= 4){

			options_bitmap_new.inSampleSize = 6;
			quality = 80;
		}else if(scale >= 2){		
			options_bitmap_new.inSampleSize = 4;
			quality = 80;
		}else if (scale >= 1){		
			options_bitmap_new.inSampleSize = 2;
			quality = 80;
		}else{
			options_bitmap_new.inSampleSize =1;
			quality = 100;
		}

		
		Bitmap bitmap =  BitmapFactory.decodeFile(imgFilePath,options_bitmap_new);
		
		bitmap = rotate(bitmap, exifDegree);
		
		byte[] buffer_bitmap =getbitmap(bitmap,quality);
		
		return buffer_bitmap;
	}
}
